package leetcode.review;

import org.junit.Test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author ：zsy
 * @date ：Created 2021/8/18 20:16
 * @description：
 */
public class 多线程打印输出ABC {

    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {while(true) data.printA();}).start();
        new Thread(() -> {while(true) data.printB();}).start();
        new Thread(() -> {while(true) data.printC();}).start();
    }

    static class Data {
        private int num = 1;
        private ReentrantLock lock = new ReentrantLock();
        private Condition conditionA = lock.newCondition();
        private Condition conditionB = lock.newCondition();
        private Condition conditionC = lock.newCondition();
        public void printA() {
            lock.lock();
            try {
                if (num != 1) {
                    conditionA.await();
                }
                System.out.print("A");
                num = 2;
                conditionB.signal();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void printB() {
            lock.lock();
            try {
                if (num != 2) {
                    conditionB.await();
                }
                System.out.print("B");
                num = 3;
                conditionC.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void printC() {
            lock.lock();
            try {
                if (num != 3) {
                    conditionC.await();
                }
                System.out.print("C");
                num = 1;
                conditionA.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}
